package com.cloudwave.trailends.ui;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.cloudwave.trailends.AppContext;
import com.cloudwave.trailends.Constants;
import com.cloudwave.trailends.R;
import com.cloudwave.trailends.compo.BaseActivity;
import com.cloudwave.trailends.domain.User;
import com.cloudwave.trailends.entity.ResultEntity;
import com.cloudwave.trailends.entity.UserInfoEntity;
import com.cloudwave.trailends.utils.ImageUtils;
import com.cloudwave.trailends.utils.StatisticsUtils;
import com.cloudwave.trailends.widget.dialog.ColaProgress;
import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.bitmap.BitmapDisplayConfig;
import com.lidroid.xutils.bitmap.callback.BitmapLoadFrom;
import com.lidroid.xutils.bitmap.callback.DefaultBitmapLoadCallBack;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;

/**
 * 用户信息
 * @author 龙雪
 *
 */
public class UserInfoActivity extends BaseActivity {
	private static final String TAG = "UserInfoActivity";
	
	private ImageButton btnBack;
	private TextView tvTitle;
	private ImageButton btnOK;
	
	private View rlUsername;
	private View rlGender;
	private View rlAge;
	private View rlWeight;
	private View rlCity;
	
	private ImageView ivAvatar;
	private TextView tvUsername;
	private TextView tvGender;
	private TextView tvAge;
	private TextView tvWeight;
	private TextView tvCity;
	
	private BitmapUtils bitmapUtils;
	
	private String localAvatarUrl;
	private String uploadToken;
	
	private boolean isUploadAvatarOk = false;
	
	private ColaProgress cp = null;
	
	private User u = null;
	private UserInfoEntity userInfo = null;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.user_info);
		
        iniView();
        
        initData();
    }
	
	private void iniView() {
		btnBack = (ImageButton) findViewById(R.id.btnBack);
		tvTitle = (TextView) findViewById(R.id.tvTitle);
		btnOK = (ImageButton) findViewById(R.id.btnOK);
		
		tvTitle.setText("个人资料");
		btnOK.setVisibility(View.VISIBLE);
		
		rlUsername = findViewById(R.id.rlUsername);
		rlGender = findViewById(R.id.rlGender);
		rlAge = findViewById(R.id.rlAge);
		rlWeight = findViewById(R.id.rlWeight);
		rlCity = findViewById(R.id.rlCity);
		
		ivAvatar = (ImageView) findViewById(R.id.ivAvatar);
		tvUsername = (TextView) findViewById(R.id.tvUsername);
		tvGender = (TextView) findViewById(R.id.tvGender);
		tvAge = (TextView) findViewById(R.id.tvAge);
		tvWeight = (TextView) findViewById(R.id.tvWeight);
		tvCity = (TextView) findViewById(R.id.tvCity);
		
		
		btnBack.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				endThis();
			}
		});
		btnOK.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				updateUserInfo();
			}
		});
		
		ivAvatar.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				selectAvatar();
			}
		});
		rlUsername.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				
			}
		});
		rlGender.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				editGender();
			}
		});
		rlAge.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				editAge();
			}
		});
		rlWeight.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				editWeight();
			}
		});
		rlCity.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				editCity();
			}
		});
	}
	
	private void initData() {
		u = ((AppContext) getApplication()).loadLoginUser();
//		userInfo = ((AppContext) getApplication()).loadLoginUserInfo();
		
		if ( userInfo == null ) {
			userInfo = new UserInfoEntity(u);
		}
		
		tvUsername.setText(u.getUserName());
		tvGender.setText(userInfo.getGenderText());
		tvAge.setText(userInfo.getAge()==null?"未知":String.valueOf(userInfo.getAge()));
		tvWeight.setText(userInfo.getWeight()==null?"未知":userInfo.getWeight()+"kg");
		tvCity.setText(userInfo.getCity()==null?"未知":userInfo.getCity());
		
		if (u != null && !TextUtils.isEmpty(u.getAvatar())) {
//			u.getAvatar().replace("middle", "mobile");  //取80x80的头像图片
			Log.v(TAG, "user avatar:"+u.getAvatar());
			if (bitmapUtils == null) {
	            bitmapUtils = new BitmapUtils(this.getApplicationContext());
	        }
			bitmapUtils.configDefaultConnectTimeout(5000);
			bitmapUtils.configDefaultLoadFailedImage(R.drawable.avatar);
			bitmapUtils.display(ivAvatar, u.getAvatar(), new DefaultBitmapLoadCallBack<ImageView>() {
				
				@Override
				public void onLoadStarted(ImageView container,
						String uri, BitmapDisplayConfig config) {
					super.onLoadStarted(container, uri, config);
					Log.v(TAG, "onLoadStarted");
				}
				@Override
				public void onLoading(ImageView container, String uri,
						BitmapDisplayConfig config, long total, long current) {
					super.onLoading(container, uri, config, total, current);
//					container.setImageResource(R.drawable.avatar);  //设置了这一行代码之后头像就不能正常显示了#BUG#
					Log.v(TAG, "onLoading");
				}
				@Override
				public void onLoadCompleted(ImageView container, String uri,
						Bitmap bitmap, BitmapDisplayConfig config,
						BitmapLoadFrom from) {
					super.onLoadCompleted(container, uri, bitmap, config, from);
//					fadeInDisplay(container, bitmap);
					fadeInDisplay(container, ImageUtils.toRoundCorner(bitmap, 80));
//			        container.setImageBitmap(ImageUtils.toRoundCorner(bitmap, 80));
			        
					Log.v(TAG, "onLoadCompleted");
				}

				@Override
				public void onLoadFailed(ImageView container, String uri,
						Drawable drawable) {
					container.setImageResource(R.drawable.avatar);
					Log.v(TAG, "onLoadFailed");
				}
				
			});
		}
	}
	
	private static final ColorDrawable TRANSPARENT_DRAWABLE = new ColorDrawable(android.R.color.transparent);
	
	private void fadeInDisplay(ImageView imageView, Bitmap bitmap) {
        final TransitionDrawable transitionDrawable =
                new TransitionDrawable(new Drawable[]{
                        TRANSPARENT_DRAWABLE,
                        new BitmapDrawable(imageView.getResources(), bitmap)
                });
        imageView.setImageDrawable(transitionDrawable);
        transitionDrawable.startTransition(500);
    }
	
	private void editGender() {
		new AlertDialog.Builder(this)
		.setTitle("请选择您的性别")
		.setIcon(android.R.drawable.ic_dialog_info)                
		.setSingleChoiceItems(R.array.user_info_gender, 0, 
		  new DialogInterface.OnClickListener() {
		     public void onClick(DialogInterface dialog, int which) {
		    	 String[] arr = getResources().getStringArray(R.array.user_info_gender);
		    	 tvGender.setText(arr[which]);
		         dialog.dismiss();
		     }
		  }
		)
		.setNegativeButton("取消", null)
		.show();
	}
	
	private void editAge() {
		new AlertDialog.Builder(UserInfoActivity.this)
		.setTitle("请选择您的年龄")
		.setIcon(android.R.drawable.ic_dialog_info)                
		.setSingleChoiceItems(R.array.user_info_age, 0, 
		  new DialogInterface.OnClickListener() {
		     public void onClick(DialogInterface dialog, int which) {
		    	 String[] arr = getResources().getStringArray(R.array.user_info_age);
		    	 tvAge.setText(arr[which]);
		         dialog.dismiss();
		     }
		  }
		)
		.setNegativeButton("取消", null)
		.show();
	}
	
	private void editWeight() {
		new AlertDialog.Builder(UserInfoActivity.this)
		.setTitle("请选择您的体重")
		.setIcon(android.R.drawable.ic_dialog_info)                
		.setSingleChoiceItems(R.array.user_info_weight, 0, 
		  new DialogInterface.OnClickListener() {
		     public void onClick(DialogInterface dialog, int which) {
		    	 String[] arr = getResources().getStringArray(R.array.user_info_weight);
		    	 tvWeight.setText(arr[which]);
		    	 dialog.dismiss();
		     }
		  }
		)
		.setNegativeButton("取消", null)
		.show();
	}
	
	private void editCity() {
		final EditText et = new EditText(UserInfoActivity.this);
		new AlertDialog.Builder(UserInfoActivity.this)
		.setTitle("请输入您所在的城市")
		.setIcon(android.R.drawable.ic_dialog_info)
		.setView(et)
		.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if ( !TextUtils.isEmpty(et.getText()) ) {
					 tvCity.setText(et.getText());
			    	 dialog.dismiss();
				}
			}
		})
		.setNegativeButton("取消", null)
		.show();
	}
	
	
	private void selectAvatar() {
		new AlertDialog.Builder(this)
		.setTitle("设置头像...")
		.setNegativeButton("相册", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				/**
				 * 刚开始，我自己也不知道ACTION_PICK是干嘛的，后来直接看Intent源码，
				 * 可以发现里面很多东西，Intent是个很强大的东西，大家一定仔细阅读下
				 */
				Intent intent = new Intent(Intent.ACTION_PICK, null);

				/**
				 * 下面这句话，与其它方式写是一样的效果，如果：
				 * intent.setData(MediaStore.Images
				 * .Media.EXTERNAL_CONTENT_URI);
				 * intent.setType(""image/*");设置数据类型
				 * 如果朋友们要限制上传到服务器的图片类型时可以直接写如
				 * ："image/jpeg 、 image/png等的类型"
				 */
				intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
				startActivityForResult(intent, 1);
			}
		})
		.setPositiveButton("相机拍照", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				 String sdStatus = Environment.getExternalStorageState();
				 if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
					 	Toast.makeText(UserInfoActivity.this, "木有SD卡哦!", Toast.LENGTH_SHORT).show();
		                Log.v(TAG, "SD card is not avaiable/writeable right now.");
		                return;
		            }
				/**
				 * 下面这句还是老样子，调用快速拍照功能，至于为什么叫快速拍照，大家可以参考如下官方
				 * 文档，you_sdk_path/docs/guide/topics/media/camera.html
				 * 我刚看的时候因为太长就认真看，其实是错的，这个里面有用的太多了，所以大家不要认为
				 * 官方文档太长了就不看了，其实是错的
				 */
				Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				// 下面这句指定调用相机拍照后的照片存储的路径
				intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri
						.fromFile(new File(Environment.getExternalStorageDirectory(), "onriding_avatar.jpg")));
				startActivityForResult(intent, 2);
			}
		}).show();
	}
	
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if ( data == null ) {
			return ;
		}
		switch (requestCode) {
		// 如果是直接从相册获取
		case 1:
			startPhotoZoom(data.getData());
			break;
		// 如果是调用相机拍照时
		case 2:
			File temp = new File(Environment.getExternalStorageDirectory() + "/onriding_avatar.jpg");
			startPhotoZoom(Uri.fromFile(temp));
			break;
		// 取得裁剪后的图片
		case 3:
			/**
			 * 非空判断大家一定要验证，如果不验证的话， 在剪裁之后如果发现不满意，要重新裁剪，丢弃
			 * 当前功能时，会报NullException，只 在这个地方加下，大家可以根据不同情况在合适的 地方做判断处理类似情况
			 */
			setPicToView(data);
			break;
		default:
			break;

		}
		super.onActivityResult(requestCode, resultCode, data);
	}
	
	/**
	 * 裁剪图片方法实现
	 * 
	 * @param uri
	 */
	public void startPhotoZoom(Uri uri) {
		/*
		 * 至于下面这个Intent的ACTION是怎么知道的，大家可以看下自己路径下的如下网页
		 * yourself_sdk_path/docs/reference/android/content/Intent.html
		 * 直接在里面Ctrl+F搜：CROP ，之前没仔细看过，其实安卓系统早已经有自带图片裁剪功能, 是直接调本地库的
		 */
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
		intent.putExtra("crop", "true");
		// aspectX aspectY 是宽高的比例
		intent.putExtra("aspectX", 1);
		intent.putExtra("aspectY", 1);
		// outputX outputY 是裁剪图片宽高
		intent.putExtra("outputX", 128);
		intent.putExtra("outputY", 128);
		intent.putExtra("return-data", true);
		startActivityForResult(intent, 3);
	}

	/**
	 * 保存裁剪之后的图片数据
	 * 
	 * @param picdata
	 */
	private void setPicToView(Intent picdata) {
		Bundle extras = picdata.getExtras();
		if ( extras != null ) {
			Bitmap bitmap = extras.getParcelable("data");
			FileOutputStream b = null;
            long userId = ((AppContext) getApplication()).getUid();
            File fDir = new File(getCacheDir(), "avatar");
            
            if (!fDir.exists() && !fDir.mkdirs()) {
            	Toast.makeText(UserInfoActivity.this, "创建文件夹失败,请检查您的内存卡~_~", Toast.LENGTH_SHORT).show();
            	Log.e(TAG, "创建文件夹失败！");
            	return ;
            } 
           
            File saveFile = new File(fDir, userId+".png");
            if ( !saveFile.exists() ) {
            	
            	try {
					saveFile.createNewFile();
				} catch (IOException e) {
					Log.e(TAG, e.getMessage());
					Toast.makeText(UserInfoActivity.this, "创建文件失败~_~", Toast.LENGTH_SHORT).show();
					return ;
				}
            }
			
            try {
                b = new FileOutputStream(saveFile);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, b);// 把数据写入文件
            } catch (FileNotFoundException e) {
                Log.e(TAG, e.getMessage());
            } finally {
                try {
                    b.flush();
                    b.close();
                } catch (IOException e) {
                	Log.e(TAG, e.getMessage());
                }
            }
            
            ivAvatar.setImageBitmap(bitmap);// 将图片显示在ImageView里
//            ivAvatar.setTag(f.getPath());
//			((AppContext) getApplication()).put("user.avatar", bitmap, 60 * ACache.TIME_DAY);
//			uploadAvatar(saveFile.getAbsolutePath());
			
			localAvatarUrl = saveFile.getAbsolutePath();
			getQiniuUploadToken();
		}
	}
	
	private void getQiniuUploadToken() {
		if ( cp == null ) {
			cp = ColaProgress.show(UserInfoActivity.this, "", true, false, null);
		}
		cp.show();
		
		RequestParams params = new RequestParams();
		StatisticsUtils.newInstance(this).appendParams("1", params);
		params.addBodyParameter("token", ((AppContext) getApplication()).getToken());
		params.addBodyParameter("action", "avatar");
		
		HttpUtils http = new HttpUtils();
		http.send(HttpRequest.HttpMethod.POST, Constants.URL_USER_UPLOAD_TOKEN, params, new RequestCallBack<String>() {
			@Override
			public void onSuccess(ResponseInfo<String> responseInfo) {
				if (responseInfo.statusCode != 200 && TextUtils.isEmpty(responseInfo.result)) {
					Toast.makeText(UserInfoActivity.this, "上传失败,请重试~_~", Toast.LENGTH_SHORT).show();
					cp.dismiss();
					return ;
				}
				ResultEntity rt = JSON.parseObject(responseInfo.result, ResultEntity.class);
				if ( !rt.isSuccess() ) {
					Toast.makeText(UserInfoActivity.this, rt.getCodeMsg(), Toast.LENGTH_SHORT).show();
					cp.dismiss();
					return ;
				} else {
					if ( !rt.hasData() ) {
//						ivAvatar.setImageResource(R.drawable.avatar);
						Toast.makeText(UserInfoActivity.this, "上传失败,未获取到数据~_~", Toast.LENGTH_SHORT).show();
						cp.dismiss();
					} else {
						uploadToken = rt.getData().toString();
						uploadAvatar();
					}
				}
			}
			
			@Override
			public void onFailure(HttpException error, String msg) {
				Toast.makeText(UserInfoActivity.this, "更新失败,请检查您的网络~_~", Toast.LENGTH_SHORT).show();
//				ivAvatar.setImageResource(R.drawable.avatar);
				cp.dismiss();
				Log.e(TAG, error.getMessage());
			}
		});
	}
	
	private void uploadAvatar() {
		if ( TextUtils.isEmpty(localAvatarUrl) || TextUtils.isEmpty(uploadToken) ) {
			Toast.makeText(UserInfoActivity.this, "数据丢失,请重试~_~", Toast.LENGTH_SHORT).show();
			cp.dismiss();
			return ;
		}
		
		UploadManager uploadManager = ((AppContext) getApplication()).getUploadManager();
		uploadManager.put(localAvatarUrl, null, uploadToken, new UpCompletionHandler() {

			@Override
			public void complete(String str,
					com.qiniu.android.http.ResponseInfo responseInfo, JSONObject jsonObj) {
				Log.i(TAG, responseInfo.toString());
				try {
					updateUserAvatarCache(jsonObj.getString("url"));
				} catch (JSONException e) {
					Log.e(TAG, e.getMessage());
					cp.dismiss();
					Toast.makeText(UserInfoActivity.this, "读取返回值异常~_~", Toast.LENGTH_SHORT).show();
				}
			}
	    }, null);
	}
	
	private void updateUserAvatarCache(String remoteUrl) {
		User u = ((AppContext) getApplication()).loadLoginUser();
		if (u != null) {
//			u.setLocalAvatar(localAvatarUrl);
			u.setAvatar(remoteUrl);
		}
		((AppContext) getApplication()).updateLoginUser(u);
		isUploadAvatarOk = true;
		cp.dismiss();
		Toast.makeText(UserInfoActivity.this, "头像修改成功^_^", Toast.LENGTH_SHORT).show();
	}
	
	
	private void updateUserInfo() {
		UserInfoEntity userInfo = new UserInfoEntity();
		userInfo.setUserId(u.getId());
		
		readProp(userInfo);
		
		if ( !userInfo.equals(this.userInfo) ) {
			dealUpdateUserInfo(Constants.URL_USER_INFO_UPDATE, userInfo);
		} else {
			Toast.makeText(UserInfoActivity.this, "无内容变更", Toast.LENGTH_SHORT).show();
		}
	}
	
	private void dealUpdateUserInfo(String url, UserInfoEntity userInfo) {
		if ( cp == null ) {
			cp = ColaProgress.show(UserInfoActivity.this, "", true, false, null);
		}
		cp.show();
		
		RequestParams params = new RequestParams();
		StatisticsUtils.newInstance(this).appendParams("1", params);
		params.addBodyParameter("token", ((AppContext) getApplication()).getToken());
		params.addBodyParameter("data", JSON.toJSONString(userInfo));
		
		HttpUtils http = new HttpUtils();
		http.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
			@Override
			public void onSuccess(ResponseInfo<String> responseInfo) {
				if (responseInfo.statusCode != 200 
						&& TextUtils.isEmpty(responseInfo.result)) {
//					resetUserInfo();
					cp.dismiss();
					Toast.makeText(UserInfoActivity.this, "更新失败,请重试~_~", Toast.LENGTH_SHORT).show();
					return ;
				}
				ResultEntity rt = JSON.parseObject(responseInfo.result, ResultEntity.class);
				if ( !rt.isSuccess() ) {
//					resetUserInfo();
					cp.dismiss();
					Toast.makeText(UserInfoActivity.this, rt.getCodeMsg(), Toast.LENGTH_SHORT).show();
					return ;
				} else {
					afterUpdateUserInfo();
				}
			}
			
			@Override
			public void onFailure(HttpException error, String msg) {
				Toast.makeText(UserInfoActivity.this, "更新失败,请检查您的网络~_~", Toast.LENGTH_SHORT).show();
//				resetUserInfo();
				cp.dismiss();
				Log.e(TAG, error.getMessage());
			}
		});
	}
	
	private void afterUpdateUserInfo() {
		UserInfoEntity info = new UserInfoEntity();
		
		readProp(info);
		
		this.userInfo = info;
//		((AppContext) getApplication()).updateLoginUserInfo(userInfo);
		u.updateBaseInfo(userInfo);
		((AppContext) getApplication()).updateLoginUser(u);
		
		Toast.makeText(UserInfoActivity.this, "更新成功^_^", Toast.LENGTH_SHORT).show();
		this.finish();
	}
	
	private void readProp(UserInfoEntity info) {
		if ( !TextUtils.isEmpty(tvAge.getText()) 
				&& !"未知".equals(tvAge.getText()) ) {
			info.setAge(Integer.parseInt(tvAge.getText().toString()));
		}
		
		if ( !TextUtils.isEmpty(tvWeight.getText()) 
				&& !"未知".equals(tvWeight.getText()) ) {
			info.setWeight(Float.parseFloat(tvWeight.getText().toString().replace("kg", "")));
		}
		
		if ( !TextUtils.isEmpty(tvGender.getText()) 
				&& !"未知".equals(tvGender.getText()) ) {
			info.setGenderText(tvGender.getText().toString());
		}
		
		if ( !TextUtils.isEmpty(tvCity.getText()) 
				&& !"未知".equals(tvCity.getText()) ) {
			info.setCity(tvCity.getText().toString());
		}
	}
	
	@Override
	public void onBackPressed() {
		endThis();
	}
	
	private void endThis() {
		if ( isUploadAvatarOk ) {
			this.setResult(1);
		}
		this.finish();
	}
	
}
